Home:ALL Converter>Angular Pipe not working on child routes

Angular Pipe not working on child routes

Ask Time:2018-06-01T16:55:17         Author:Ehsan Zargar Ershadi

Json Formatter

I have a very simple Pipe in Angular 5

import { Pipe, Injectable } from '@angular/core';

@Pipe({
    name: "default"
})
@Injectable()
export class DefaultPipe {
    transform(value: string, fallback: string): string {
        let image = "";
        if (value) {
            image = value;
        } else {
            image = fallback;
        }
        return image;
    }
}

and I use it in a very simple way just for demonstration

<div>
    {{ 'somthing' | default }}
</div> 

I have also added in provider section in app.module.ts

@NgModule({
    declarations: [
        AppComponent,
        DefaultPipe // <-- Here
    ],
    imports: [
        ....
    ],
    providers: [
        ....
    ],
    bootstrap: [AppComponent]
})
export class AppModule { }

when you use it in an normal component such as

app.component.html

it works fine, but if you use it in a component which is used in a child route it gives this error:

compiler.js:486 Uncaught Error: Template parse errors: The pipe 'default' could not be found ("

{{[ERROR ->] 'somthing' | default }} "): ng:///AppRoutingModule/LoginComponent.html@75:6 at syntaxError (compiler.js:486) at TemplateParser.webpackJsonp../node_modules/@angular/compiler/esm5/compiler.js.TemplateParser.parse (compiler.js:24674) at JitCompiler.webpackJsonp../node_modules/@angular/compiler/esm5/compiler.js.JitCompiler._parseTemplate (compiler.js:34629) at JitCompiler.webpackJsonp../node_modules/@angular/compiler/esm5/compiler.js.JitCompiler._compileTemplate (compiler.js:34604) at compiler.js:34505 at Set.forEach () at JitCompiler.webpackJsonp../node_modules/@angular/compiler/esm5/compiler.js.JitCompiler._compileComponents (compiler.js:34505) at compiler.js:34375 at Object.then (compiler.js:475) at JitCompiler.webpackJsonp../node_modules/@angular/compiler/esm5/compiler.js.JitCompiler._compileModuleAndComponents (compiler.js:34374)

To Solve:

I added this module as share.module.ts

import { NgModule } from '@angular/core';
import { DefaultPipe } from './core/pipes/default.pipe';

@NgModule({
    declarations: [DefaultPipe],
    exports: [DefaultPipe]
})
export class SharedModule { }

and used it in 2 places, one in app.module.ts:

@NgModule({
declarations: [
    AppComponent,
],
imports: [
    ...
    // other modules
    ...
    SharedModule
],
providers: [
    ....
],
bootstrap: [AppComponent]

}) export class AppModule { }

and one in route.module.ts

@NgModule({
    declarations: [
        ....
    ],
    imports: [
        ....
        SharedModule
    ],
    exports: [
        RouterModule,
    ]
})

export class AppRoutingModule { }

Author:Ehsan Zargar Ershadi,eproduced under the CC 4.0 BY-SA copyright license with a link to the original source and this disclaimer.
Link to original article:https://stackoverflow.com/questions/50639623/angular-pipe-not-working-on-child-routes
SrAxi :

The best practice for creating helper components, pipes or directives is to create a SharedModule and put that stuff inside.\n\nComponents, Directives and Pipes don't work like services. A service you can inject it in the AppModule's services array and that will work for children too.\n\nA Pipe, Directive or Component you have to declare them in an NgModule and then import it where you need it, because they can ONLY belong to 1 Module. (But that module can be imported as many times as you want!)\n\nTherefore, the best thing you could do is to create a SharedModule with the following:\n\n@NgModule({\n imports: [ ... ],\n declarations: [ DefaultPipe ],\n exports: [ DefaultPipe ]\n})\nexport class SharedModule { }\n\n\nAnd then in AppModule you import SharedModule like this:\n\nimports: [ SharedModule ]\n\n\nAnd now, if you want to use it in your LoginComponent or in any other part of your application, you import your SharedModule in the module for that component.",
2018-06-01T09:16:17
Jota.Toledo :

You dont need to use the Injectable decorator on the pipe, so you can remove that.\nFurthermore, as already suggested in other answers, I would recommend you to explicitely implement the PipeTransform interface in order to be consistent with the pipe API.\n\ncompiler.js:486 Uncaught Error: Template parse errors: The pipe 'default' could not be found ("\n{{[ERROR ->] 'somthing' | default }} "): ng:///AppRoutingModule/LoginComponent.html@75:6 at syntaxError (compiler.js:486)\n\nis basically saying that your pipe wasnt neither declared or imported in the module, in whichLoginComponent is declared.\nThe simplest and cleanest solution would be to declare/export the pipe inside of a new NgModule class, that you can then import into every module that declares a component that uses the pipe. For example:\n@NgModule({\n declarations: [DefaultPipe],\n exports: [DefaultPipe]\n})\nexport class DefaultPipeModule{}\n\n@NgModule({\n imports: [DefaultPipeModule],\n declarations: [LoginComponent]\n})\nexport class FooModule {}\n\n@NgModule({\n imports: [DefaultPipeModule],\n declarations: [FooComponent] // fooComponent also uses the default pipe, so we need to import its module\n})\nexport class SomeOtherModule{}\n",
2018-06-01T09:01:35
yy